import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

import random
from google.appengine.dist import use_library
use_library('django', '1.2')
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

#EVERYTHING WE NEED TO SHOW USER MAP#
class DataObject(db.Model):
  usrMap = db.StringProperty(required= True)
  mine_map=db.StringProperty(required=True)
  level = db.StringProperty(required= True)
  rows = db.IntegerProperty(required=True)
  columns = db.IntegerProperty(required=True)
  mine_percent = db.IntegerProperty(required=True)
"""
class GameObject(class):
  def __init__(self, key):
    pass
  
  def LoadFromDatastore(encoded_key):
    data_object = db.get(key)
    game = MineSweeper(data_object.rows, data_object.columns, data_object.mine_percent)
    game.num_mines = data_object.num_mines
    ###de-chunk maps, and store them in the game object####

    game.data_object = data.object
    return game	

  def saveToDatastore(self):
    ###return an encoded key ###
    if self.data_object is None:
      self.data_object = DataObject()
    ###populate data object####

    self.data_object.mine_list = flat_map
    self.data_object.put()
    return str(self.data_object.key())
"""

"""Creates Minesweeper with rows, columns, and percent of mines"""
class MineSweeper(object):

  BLANK = ' '
  ZERO = 0

  def __init__(self, rows, columns, mine_percent):
    self.board_size = (rows, columns)
    self.mine_map = [[0 for _ in xrange(columns)] for _ in xrange(rows)]
    self.mine_percent = mine_percent
    self.num_mines = 0
    self.data_object = None

  def NewGame(self): 
    rows, columns = self.board_size
    for row_index, row in enumerate(self.mine_map):
      for column_index, column in enumerate(row):
        if random.randint(1, 100) <= self.mine_percent:
          self.mine_map[row_index][column_index] = -1
          self.num_mines += 1
        else:
          self.mine_map[row_index][column_index] = 0
    self.markMap()

  
  def compare(self, usrMap, cellLocations):
    usrX,usrY=cellLocations.split(",")

    usrX = int(usrX)
    usrY = int(usrY)
    usrX -= 1
    usrY -= 1
    #if you hit a zero, clear the field# 
    if self.mine_map[usrY][usrX]==0:
      self.clrField(usrY,usrX,usrMap)
      
    #if you hit a mine# 
    elif self.mine_map[usrY][usrX]==-1:
      usrMap[usrY][usrX]=-1
      
    #if you press a number rather than zero or hit a mine it should return/display the specific number#  
    else:
      usrMap[usrY][usrX]=self.mine_map[usrY][usrX]
       
     

  def markMap(self):
    for yi,y in enumerate(self.mine_map):
      for xi,x in enumerate(y):
        if x == -1 and yi > 0 and xi > 0:
          if self.mine_map[yi-1][xi-1] != -1:
             self.mine_map[yi-1][xi-1] += 1
	if x == -1 and yi > 0:
          if self.mine_map[yi-1][xi] != -1:
	     self.mine_map[yi-1][xi] += 1
        if x == -1 and yi > 0 and xi+1 < len(y):
          if self.mine_map[yi-1][xi+1] != -1:
	     self.mine_map[yi-1][xi+1] += 1
	if x == -1 and xi > 0:
	  if self.mine_map[yi][xi-1] != -1:
	     self.mine_map[yi][xi-1] += 1
	if x == -1 and xi+1 < len(y):
	  if self.mine_map[yi][xi+1] != -1:
	     self.mine_map[yi][xi+1] += 1
	if x == -1 and yi+1<len(self.mine_map) and x>0:
          if self.mine_map[yi+1][xi-1] != -1:
	     self.mine_map[yi+1][xi-1] += 1
	if x == -1 and yi+1<len(self.mine_map):
	  if self.mine_map[yi+1][xi] != -1:
	     self.mine_map[yi+1][xi] += 1
	if x == -1 and yi+1<len(self.mine_map) and xi+1<len(y):
	  if self.mine_map[yi+1][xi+1] != -1:
	     self.mine_map[yi+1][xi+1] += 1
    for yi,y in enumerate(self.mine_map):
      for xi,x in enumerate(y):
          self.mine_map[yi][xi] = str(self.mine_map[yi][xi])
    return self.mine_map 

  def clrField(self,y,x,usrMap):
      
    if usrMap[y-1][x-1]==self.BLANK and  y > 0 and x > 0:
      usrMap[y-1][x-1] = self.mine_map[y-1][x-1]
      if usrMap[y-1][x-1] == self.ZERO:
	self.clrField(y-1,x-1, usrMap)
    if usrMap[y-1][x]==self.BLANK and y > 0:
      usrMap[y-1][x] = self.mine_map[y-1][x]
      if usrMap[y-1][x] == self.ZERO:
	self.clrField(y-1,x, usrMap)
    if usrMap[y-1][x+1]==self.BLANK and y > 0 and x+1 < len(self.mine_map[0]):
      usrMap[y-1][x+1]= self.mine_map[y-1][x+1]
      if usrMap[y-1][x+1] == self.ZERO:
        self.clrField(y-1,x+1, usrMap)
    if usrMap[y][x-1]==self.BLANK and x > 0:
      usrMap[y][x-1]=self.mine_map[y][x-1]
      if usrMap[y][x-1] == self.ZERO:
        self.clrField(y,x-1, usrMap)
    if usrMap[y][x+1]==self.BLANK and x+1 < len(self.mine_map[0]):
      usrMap[y][x+1]=self.mine_map[y][x+1]
      if usrMap[y][x+1] == self.ZERO:
        self.clrField(y,x+1, usrMap)
    if usrMap[y+1][x-1]==self.BLANK and y+1<len(self.mine_map) and x>0:
      usrMap[y+1][x-1]=self.mine_map[y+1][x-1]
      if usrMap[y+1][x-1] == self.ZERO:
        self.clrField(y+1,x-1, usrMap)
    if usrMap[y+1][x]==self.BLANK and y+1<len(self.mine_map):
      usrMap[y+1][x]=self.mine_map[y+1][x]
      if usrMap[y+1][x] == self.ZERO:
	self.clrField(y+1,x, usrMap)
    if usrMap[y+1][x+1]==self.BLANK and y+1<len(self.mine_map) and x+1<len(self.mine_map[0]):
      usrMap[y+1][x+1]=self.mine_map[y+1][x+1]
      if usrMap[y+1][x+1] == self.ZERO:
        self.clrField(y+1,x+1, usrMap)

"""Displays home page"""
class HomeHandler(webapp.RequestHandler):
  def get(self):
    template_values= {}
    """Telling get method to display the home page"""
    path = os.path.join(os.path.dirname(__file__), 'home.html')
    self.response.out.write(template.render(path, template_values))

class NewGameHandler(webapp.RequestHandler):
  game=MineSweeper(6,6,20)

  """ Convert user map to string for database"""
  def makeMapToString(self, usrMap):
    #a is an array holding mineMap; s is the string we are storing the array in and ultimately return #
    a = usrMap
    s = ""
    for row in range(len(a)):
      for column in range(len(a)):
        s += str(a[row][column])
        if column < (len(a)-1):
          s += ","
      if row < (len(a)-1):  
        s += "/"
    return s
    return ""
  
  #Converts string from database back to user map# 
  def makeStringToMap(self, stringMap):
    x = stringMap.split('/')
    a = []
    for row in range(len(x)):
      a.append(x[row].split(","))
      for column in range(len(x)):
        value = a[row][column]
        a[row][column] = None if value == 'None' else int(value)
        #a[row][column]= int(a[row][column])
    return a


  """ Make a usermap and return a list of list of strings."""
  def makeBlankUserMap(self):
    level=self.request.get('level')
    usrMap = []
    if level == 'easy':
      size=6
      game=MineSweeper(6,6,20)

    elif level == 'medium':
      size=14
      game=MineSweeper(14,14,40)

    else:
      size=20
      game=MineSweeper(20,20,60)
    
    game.NewGame()
    for i in range(size):
      row= []
      for j in range(size):
        row.append(None)
      usrMap.append(row)
      
      stringMap= self.makeMapToString(usrMap)
      stringMineMap = self.makeMapToString(game.mine_map)
      rows, columns = game.board_size
      # change usrMap to a string#
      data_object = DataObject(level= level, usrMap = stringMap, mine_map=stringMineMap,
                               rows=rows, columns=columns, 
                               mine_percent =game.mine_percent)
      data_object.put()
      gamekey= str(data_object.key())
   
    return (usrMap, gamekey)


  """Makes and stores a new game then directs user to GameHandler."""
  def get(self):
    usrMap, gamekey = self.makeBlankUserMap()
    level=self.request.get('level')
    # Built empty user map need to store in database#
    #Telling get method to display user map#
    template_values= { 'usrMap': usrMap, 'level': level, 'gamekey':gamekey }
    path = os.path.join(os.path.dirname(__file__), 'game.html')
    self.response.out.write(template.render(path, template_values))

  """Called when a button is clicked by the user on the user map"""
  def post(self):
    # cellLocations is a string type that returns cell's "row, column"#
    cellLocations = self.request.get("cell")
    # compare the user map value to the mine map value of cellLocation's coordinates#

    locations = self.request.get("storeValues") 
    locations = locations + cellLocations
    

    gamekey=self.request.get("gamekey")
    key=db.Key(encoded=gamekey)
    data_object=db.get(key)
    usrMap=self.makeStringToMap(data_object.usrMap)

    game = MineSweeper(data_object.rows, data_object.columns, data_object.mine_percent)
    game.mine_map = self.makeStringToMap(data_object.mine_map)
    #game logic compare()#
    game.compare(usrMap, cellLocations)
    data_object.usrMap=self.makeMapToString(usrMap)
    data_object.put()
    template_values = { 'locations': locations,'usrMap':usrMap , 'level': data_object.level, 'gamekey':gamekey}

    path = os.path.join(os.path.dirname(__file__), 'game.html')
    self.response.out.write(template.render(path, template_values))




def main():
  application = webapp.WSGIApplication([('/home.*', HomeHandler),
                                        ('/game.*', NewGameHandler)],
                                        debug=True)
  run_wsgi_app(application)

if __name__ == '__main__':
  main()
